/**
 * 
 */

package org.spring.cloud.pilot.endpoint;

import java.util.Collections;
import java.util.Map;


import org.springframework.boot.SpringApplication;
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.client.serviceregistry.ServiceRegistry;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.jmx.export.annotation.ManagedResource;

/**
 * 服务暂停 ClassName: StopEndpoint <br/>
 * Function: TODO ADD FUNCTION. <br/>
 * Reason: TODO ADD REASON(可选). <br/>
 * date: 2019年10月16日 下午7:16:30 <br/>
 *
 * @author admin
 * @version
 * @since JDK 1.8
 */
@RefreshScope
@ConfigurationProperties("endpoints.stop")
@ManagedResource
public class StopEndpoint extends AbstractEndpoint<Map<String, Object>>
    implements ApplicationListener<ApplicationPreparedEvent> {
    
    private static final Map<String, Object> NO_CONTEXT_MESSAGE = Collections
        .unmodifiableMap(Collections.<String, Object>singletonMap("message",
                "No context to shutdown."));

private static final Map<String, Object> SHUTDOWN_MESSAGE = Collections
        .unmodifiableMap(Collections.<String, Object>singletonMap("message",
                "stopping down, bye..."));

    private ConfigurableApplicationContext context;

    private SpringApplication application;

    private String[] args;

    private ApplicationPreparedEvent event;

    private ServiceRegistry serviceRegistry;

    private Registration registration;

    public StopEndpoint(String id) {
        super("stop", true, false);
    }

    @Override
    public Map<String, Object> invoke() {
        if (this.context == null) {
            return NO_CONTEXT_MESSAGE;
        }
        try {
            return SHUTDOWN_MESSAGE;
        } finally {
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        Thread.sleep(500L);
                    } catch (InterruptedException ex) {
                        Thread.currentThread().interrupt();
                    }
                    context.close();
                }
            });
            thread.setContextClassLoader(getClass().getClassLoader());
            thread.start();
        }

    }

    @Override
    public void onApplicationEvent(ApplicationPreparedEvent input) {
        this.event = input;
        if (this.context == null) {
            this.context = this.event.getApplicationContext();
            this.args = this.event.getArgs();
            this.application = this.event.getSpringApplication();
            this.serviceRegistry = this.context.getBean(ServiceRegistry.class);
            this.registration = this.context.getBean(Registration.class);

        }
    }

}
